home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 …SCII & the Runetime Code / ADC Developer CD (1992-07) (''Butch ASCII And The Runtime Code'')_iso / Dev.CD 199207.iso / Development Platforms / Apple II / HyperCardIIGS / Sample.XCMDs / XWindow Shell / XWindShell (Pascal) / XWindShell.p < prev    next >
Encoding:
Text File  |  1992-02-05  |  12.4 KB  |  332 lines  |  [TEXT/MPS ]

  1. (* ---------------------------------------------------------------------
  2.  
  3.    Pascal source for XWindShell XCMD
  4.    
  5.    Copyright © 1989-92 Apple Computer, Inc.
  6.  
  7.  
  8.    This file includes the source code for the XWindShell XCMD.  While
  9.    this XCMD will compile and execute in its current form.  The XWindow
  10.    has no functionality beyond demonstrating the basics of HyperCard's
  11.    XWindow capabilities.  This file is meant to be a basis where an
  12.    XCMD author can "fill in the blanks" to create their XCMD.  See the
  13.    other sample XCMDs such as Picture, MemState, and ListWindow for
  14.    practical examples of code dealing with responding to XWindow events
  15.    and strategies for storing information for the XWindows while they
  16.    are open.
  17.  
  18.    The files included with the XWindShell XCMD are meant to be
  19.    used as a starting point for XCMDs in C or Pascal that wish to
  20.    create and manage XWindows.
  21.  
  22.    Files:
  23.    ------
  24.     *XWindShell.p
  25.      XWindShell.r
  26.      MakeFile
  27.     
  28.     
  29.    Author:    Darin Acquistapace
  30.    Created:    01/29/92
  31.    Modified:    See Mod History Below
  32.  
  33.    Modification History:
  34.    ---------------------
  35.      01/29/92 - New today.
  36.      
  37.    ------------------------------------------------------------------ *)
  38.  
  39. UNIT DummyUnit;
  40.  
  41. {$Z+ }
  42. {$N+ }
  43.  
  44. INTERFACE
  45.  
  46. USES     
  47.     Types, Memory, MiscTool, GSOS, QuickDraw, Resources, QDAux, Events, 
  48.     Controls, Windows, HyperXCMD;
  49.     
  50. PROCEDURE EntryPoint(paramPtr: XCMDPtr);
  51.  
  52. IMPLEMENTATION
  53.  
  54. PROCEDURE XWindShell(paramPtr: XCMDPtr);                                    FORWARD;
  55.  
  56. PROCEDURE EntryPoint(paramPtr: XCMDPtr);
  57. BEGIN
  58.   XWindShell(paramPtr);
  59. END;
  60.  
  61. { Any external procedures or functions should be declared here in the form:
  62.          PROCEDURE MyExternalRoutine(inputWord: INTEGER);     EXTERNAL;
  63.         
  64.    Additionally, any functions or procedures that need to be accessed from
  65.    the toolbox or GS/OS, such as a custom item control routine, should be 
  66.    placed here. }
  67.  
  68. PROCEDURE XWindShell(paramPtr: XCMDPtr);
  69. { Definitions of any constants, types, and variables needed by the main 
  70.    routine of the XCMD or more than one nested procedure. }
  71. CONST
  72.     LeftPos            = 100;        { Window coordinates in 640 coordinates }
  73.     TopPos            = 50;
  74.     WindWidth        = 250;
  75.     WindHeight        = 60;
  76.     WindTitle        = 'SampleXWindow';
  77.     
  78.     ScriptErrStr    = 'Can''t understand arguments of XCMD XWindShell.';
  79.     CopyrightStr    = 'XWindShell XCMD v1.0" & return & "by Darin Acquistapace, 1/29/92" & return & "© 1992 Apple Computer, Inc.';
  80.     HelpStr            = 'FORM:  XWindShell';
  81.     WrongVersionStr = 'XWindShell XCMD requires HyperCard IIGS 1.1';
  82.     CreateErrStr    = 'Unable to create window';
  83.  
  84. VAR
  85.     memoryID:        INTEGER;
  86.     xWindow:        WindowPtr;
  87.     windRect:        Rect;
  88.     str:            Str255;
  89.     
  90.     
  91.     { -------------------------------------------------------------------------- }
  92.     PROCEDURE MyDisposeHandle(h: Handle);
  93.     { Checks a handle for NIL before disposing of it.  A good practice. }
  94.     BEGIN
  95.       IF h <> NIL THEN DisposeHandle(h);
  96.     END; {MyDisposeHandle}
  97.     
  98.     
  99.     { -------------------------------------------------------------------------- }
  100.     PROCEDURE ReturnResult(str: Str255);
  101.     { Puts the specified string into the result and terminates. }
  102.     BEGIN
  103.       paramPtr^.returnValue := PasToZero(str);
  104.       EXIT(XWindShell);
  105.     END; {ReturnResult}
  106.     
  107.     
  108.     { -------------------------------------------------------------------------- }
  109.     PROCEDURE HTError;
  110.     { Generates a HyperTalk error dialog box complete with Script and Cancel 
  111.       buttons. }
  112.     BEGIN
  113.       paramPtr^.returnStat := 1;
  114.       ReturnResult(ScriptErrStr);
  115.     END; {HTError}
  116.     
  117.     
  118.     { -------------------------------------------------------------------------- }
  119.     PROCEDURE CommandInfo(str: str255);
  120.     { Puts the specified string into a dialog box and terminates. }
  121.     BEGIN
  122.       SendHCmessage(Concat('answer "', str, '"')); 
  123.       EXIT(XWindShell);
  124.     END; {CommandInfo}
  125.  
  126.  
  127.     { -------------------------------------------------------------------------- }
  128.     PROCEDURE UpdateXWindow(whichWindow: WindowPtr);
  129.     { Handles updating the contents of the XWindow.  This may include drawing 
  130.       a background picture, calling DrawControls, etc.  HyperCard takes care of 
  131.       calling BeginUpdate and EndUpdate for you. This routine should only update 
  132.       the window.  Be careful not to do anything that might cause another update 
  133.       event to occur which would result in recursion. }
  134.     BEGIN
  135.     END; {UpdateXWindow}
  136.  
  137.  
  138.     { -------------------------------------------------------------------------- }
  139.     PROCEDURE CleanUpMemory(whichWindow: WindowPtr);
  140.     { Free all memory associated with the XWindow.  This could be a handle
  141.       referenced by the GetXWindowValue callback. }
  142.     BEGIN
  143.     END; {CleanUpMemory}
  144.     
  145.     
  146.     { -------------------------------------------------------------------------- }
  147.     PROCEDURE HandleWindowClick(whichWindow: WindowPtr; ourEvent: EventRecord);
  148.     { A mouseDown event has occurred in our window.  This procedure handles
  149.       tracking the click and taking whatever actions are necessary as a result
  150.       of the click. Tracking controls in XWindows is no different than doing
  151.       the same in any standard window.  FindControl and TrackControl would be
  152.       commonly used to track the click.  See the Picture and ListWindow sample
  153.       XCMDs for examples of using the control manager to handle these actions. }
  154.     BEGIN
  155.     END; {HandleWindowClick}
  156.     
  157.  
  158.     { -------------------------------------------------------------------------- }
  159.     PROCEDURE ProcessIdle(whichWindow: WindowPtr);
  160.     { Take any actions that need to be performed periodically.  This procedure
  161.       will only be called if the SetXWIdleTime callback has been called with
  162.       an interval value other than zero (the default.) }
  163.     BEGIN
  164.     END; {ProcessIdle}
  165.     
  166.     
  167.     { -------------------------------------------------------------------------- }
  168.     PROCEDURE HandleOpenEvent(whichWindow: WindowPtr);
  169.     { Perform any actions necessary before any other events are sent.  At this
  170.       point, the window is created and visible. }
  171.     BEGIN
  172.       { Allow reentrancy, if this is not set, the XWindow may lose events that
  173.         occur because of events instigated by the XCMD.  For instance, if the
  174.         mouseDown handler performs some action which causes HyperCard to close
  175.         the XWindow, the xCloseEvt will not be received because the XCMD has the
  176.         code in the mouseDown handler pending and will be returned to when Hyper-
  177.         Card finishes executing whatever task the mouseDown handler began.  This
  178.         can be set to true for both types of events in most XCMDs and set to false
  179.         temporarily if the need arises to temporarily halt recursive calls to the
  180.         XCMD. 
  181.         
  182.         If an XCMD wishes to recieve null events, it should call SetXWIdleTime
  183.          at this point with an interval other than zero.}
  184.       XWAllowReEntrancy(whichWindow, TRUE, TRUE);
  185.     END; {HandleOpenEvent}
  186.     
  187.     
  188.     { -------------------------------------------------------------------------- }
  189.     PROCEDURE HandleCursorWithin(whichWindow: WindowPtr; cursorLoc: Point);
  190.     { The mouse cursor is within the XWindow, perform any actions necessary,
  191.       such as changing the cursor shape. }
  192.     BEGIN
  193.       { Setting the passFlag to true tells HyperCard that we would like it
  194.         to handle changing the cursor to an arrow when the cursor is within
  195.         the XWindow just as it does for the built-in windows. }
  196.       paramPtr^.passFlag := TRUE;
  197.     END; {HandleCursorWithin}
  198.     
  199.     
  200.     { -------------------------------------------------------------------------- }
  201.     PROCEDURE HandleHideShow(hideFlag: BOOLEAN);
  202.     { An XCMD has called either the HideHCPalettes or ShowHCPalettes callbacks
  203.       and our visible status has changed.  An XCMD may wish to deallocate memory
  204.       used for updating the XWindow if it knows it will be hidden for a period of
  205.       time.  An example usage would be if a significant amount of memory was
  206.       required to maintain the contents of an XWindow.  A script could call an
  207.       XCMD to send the HidePalettes event when the user entered the paint tools
  208.       so that the XCMD could free what memory it could to provide more memory
  209.       for the paint buffers. }
  210.     BEGIN
  211.     END; {HandleHideShow}
  212.     
  213.     
  214.     { -------------------------------------------------------------------------- }
  215.     PROCEDURE HandleEvents;
  216.     { Handle events specific to our XWindow.  HyperCard will only send events
  217.       to the XCMD pertaining to windows it has opened.  The XCMD, however, 
  218.       should not assume that it owns only one window.  Subsequent calls to
  219.       the XCMD to create the XWindow will result in one XCMD code segment
  220.       owning multiple XWindows. This routine is similar to the main event loop
  221.       of an application, all events dealing with the XWindows the XCMD has
  222.       created will be sent here and dispatched to the appropriate routine to
  223.       respond to them. }
  224.     VAR
  225.       myEventInfo:    XWEventInfoPtr;
  226.       window:        WindowPtr;
  227.       event:        EventRecord;
  228.     BEGIN
  229.       myEventInfo := XWEventInfoPtr(paramPtr^.params[1]);
  230.       window := myEventInfo^.eventWindow;
  231.       event := myEventInfo^.event;
  232.       
  233.       CASE event.what OF
  234.         nullEvt:            ProcessIdle(window);
  235.         xOpenEvt:            HandleOpenEvent(window);
  236.         updateEvt:            UpdateXWindow(window);
  237.         mouseDownEvt:        HandleWindowClick(window, event);
  238.         xHidePalettesEvt,
  239.         xShowPalettesEvt:    HandleHideShow(event.what = xHidePalettesEvt);
  240.           xCloseEvt:            CleanUpMemory(window);
  241.         xCursorWithin:        HandleCursorWithin(window, event.where);
  242.       END; {case}
  243.     END; {HandleEvents}
  244.  
  245.  
  246.     { -------------------------------------------------------------------------- }
  247.     PROCEDURE SetUpContents(whichWindow: WindowPtr);
  248.     { Our window has been created via a call to the NewXWindow callback and is
  249.       invisible.  Now handle any initialization necessary for the XWindow such as 
  250.       calling NewControl, etc. }
  251.     BEGIN
  252.     END; {SetupContents}
  253.     
  254.     
  255.     { -------------------------------------------------------------------------- }
  256.     FUNCTION CorrectVersion: BOOLEAN;
  257.     { This returns true if the version of HyperCard is >= minVersion.  Very
  258.       important for XCMDs that use callbacks specific to 1.1 or later versions
  259.       of HyperCard IIGS.  HyperCard IIGS 1.0 will execute a BRK and take a one-
  260.       way trip to the monitor or debugger if an XCMD attempts an invalid callback
  261.       number.  HyperCard IIGS 1.1 calls the SysFail manager with the message,
  262.       "Invalid callback attempted by XCMD" if a callback numbered greater than
  263.       $38 is attempted, BTW. }
  264.     CONST
  265.       minVersion = '1.1';
  266.     VAR
  267.       tempHandle:    Handle;
  268.       tempStr:        Str255;
  269.     BEGIN
  270.       tempHandle := EvalExpr('the version');
  271.       ZeroToPas(tempHandle^, tempStr);
  272.       MyDisposeHandle(tempHandle);
  273.       CorrectVersion := tempStr >= minVersion;
  274.     END; {CorrectVersion}
  275.     
  276.  
  277.   BEGIN
  278.     { The main routine of the XCMD.  Most XWindow XCMDs will have fairly small
  279.       main routine with the majority of the bulk of the XCMD in the routines
  280.       dispatched to by the HandleEvents procedure.  This main routine simply
  281.       deals with calling HandleEvents, displaying Help or Copyright notices,
  282.       and the initial creation of the XWindow. }
  283.       
  284.     { Get the memory ID to be used for all calls to the memory manager.  This
  285.       ID will be unique to each XWindow. }
  286.     memoryID := paramPtr^.UserID;
  287.  
  288.     { If the paramCount is negative, we have been called in response to an event. }
  289.     IF paramPtr^.paramCount < 0 THEN BEGIN
  290.       HandleEvents;
  291.       EXIT(XWindShell);
  292.     END; {if}
  293.  
  294.     { Display help or copyright info in response to "?" or "!". }
  295.     IF paramPtr^.paramCount = 1 THEN BEGIN
  296.       ZeroToPas(paramPtr^.params[1]^, str);
  297.       IF str = '!' THEN CommandInfo(CopyrightStr);
  298.       IF str = '?' THEN CommandInfo(HelpStr);
  299.     END; {if}
  300.     
  301.     { Make sure we are running at least version 1.1 of HyperCard IIGS. }
  302.     IF NOT CorrectVersion THEN ReturnResult(WrongVersionStr);
  303.     
  304.     { Check for the desired number of parameters.  XCMDs with optional
  305.       parameters will need to check the paramCount for being within a 
  306.       certain range.  Only scripting errors such as an invalid paramCount
  307.       should generate a HyperTalk error.  Other problems such as invalid or
  308.       out-of-range data in the parameters should be handled by returning an
  309.       appropriate error string the the result. }
  310.     IF paramPtr^.paramCount <> 0 THEN HTError;
  311.  
  312.     { Here the XCMD should process any parameters required.  See the other
  313.       sample XCMDs for examples of using the ZeroToPas and other conversion
  314.       callbacks to convert the zero-terminated input parameters into other
  315.       forms. }
  316.     
  317.     { Create the XWindow initially invisible.  We'll show it after we
  318.       perform any needed initialization on it, such as creating controls, etc. }
  319.     SetRect(windRect, LeftPos, TopPos, LeftPos + WindWidth, TopPos + WindHeight);
  320.     xWindow := NewXWindow(windRect, WindTitle, FALSE, xWindoidStyle);        
  321.     IF xWindow = NIL THEN ReturnResult(CreateErrStr);
  322.     
  323.     { Create the contents for the window }
  324.     SetPort(xWindow);
  325.     SetUpContents(xWindow);
  326.     
  327.     { Display the window.  This will generate an update event which will be sent
  328.       immediately following the xOpenEvt. }
  329.     ShowWindow(xWindow);
  330.   END; {XWindShell}
  331.  
  332. END.    { of the dummy unit    }